package com.aggregate.pay.xinfu.support;

import com.aggregate.pay.xinfu.bean.AbstractResult;
import com.aggregate.pay.xinfu.support.utils.JSON;
import com.aggregate.pay.xinfu.support.utils.MD5;

/**
 * 接口API操作类抽象类
 * @author Moyq5
 * @date 2018年8月31日
 * @param <D>
 * @param <R>
 */
public abstract class AbstractClient<D, R extends AbstractResult> implements Client<D, R> {

	private Merch merch;
	
	public AbstractClient(Merch merch) {
		this.merch = merch;
	}
	
	@Override
	public R execute(D data) {
		R r = null;
		try {
			String json = JSON.toJson(data);
			
			String signSrc = json + merch.key();
			log.debug("请求签名内容：{}", signSrc);
			
			String sign = MD5.MD5Encode(signSrc).toLowerCase();
			
			String reqBody = String.format("req=%s&sign=%s&merid=%s", json, sign, merch.merchNo());
			log.debug("请求参数：{}", reqBody);
			
			HttpClient client = Factory.getHttpClient();
			String resBody = client.post(getApiPath(), reqBody);
			log.debug("响应参数：{}", resBody);
			
			// [json]&[sign]
			int separaterIndex = resBody.lastIndexOf("&");
			json = resBody.substring(0, separaterIndex);
			
			String resSign = resBody.substring(separaterIndex + 1);
			
			signSrc = json + merch.key();
			log.debug("响应签名内容：{}", signSrc);
			
			sign = MD5.MD5Encode(signSrc).toLowerCase();
			log.debug("响应签名结果：{}", sign);
			
			if (!sign.equals(resSign)) {
				log.warn("验签失败");
				throw new Exception("验签失败");
			}
			
			r = JSON.toObject(resBody, getResultClass());
			
		} catch (Exception e) {
			log.error("接口调用失败", e);
			try {
				r = getResultClass().newInstance();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			r.setResCode("99");
			r.setResMsg(e.getMessage());
		}
		return r;
	}
	
	protected abstract Class<R> getResultClass();
	
	protected abstract String getApiPath();
	
	
}
